"""Auth serve API schemas"""
from typing import Any, Dict, List, Optional

from dbgpt._private.pydantic import BaseModel, ConfigDict, Field, model_to_dict

from ..config import SERVE_APP_NAME_HUMP


# ========================================
# User Schemas
# ========================================
class UserRequest(BaseModel):
    """User request model"""

    id: Optional[int] = Field(None, description="User ID")
    username: str = Field(..., description="Username", min_length=3, max_length=50)
    password: Optional[str] = Field(None, description="Password", min_length=6)
    nick_name: Optional[str] = Field(None, description="Nickname", max_length=100)
    email: Optional[str] = Field(None, description="Email", max_length=100)
    phone: Optional[str] = Field(None, description="Phone number", max_length=20)
    avatar_url: Optional[str] = Field(None, description="Avatar URL", max_length=255)
    status: Optional[int] = Field(1, description="Status: 1=Active, 0=Disabled")
    remark: Optional[str] = Field(None, description="Remark", max_length=500)
    role_ids: Optional[List[int]] = Field(None, description="Role IDs")

    model_config = ConfigDict(title=f"UserRequest for {SERVE_APP_NAME_HUMP}")

    def to_dict(self, **kwargs) -> Dict[str, Any]:
        """Convert to dict"""
        return model_to_dict(self, **kwargs)


class UserResponse(BaseModel):
    """User response model"""

    id: int = Field(..., description="User ID")
    username: str = Field(..., description="Username")
    nick_name: Optional[str] = Field(None, description="Nickname")
    email: Optional[str] = Field(None, description="Email")
    phone: Optional[str] = Field(None, description="Phone number")
    avatar_url: Optional[str] = Field(None, description="Avatar URL")
    status: int = Field(..., description="Status: 1=Active, 0=Disabled")
    remark: Optional[str] = Field(None, description="Remark")
    roles: Optional[List["RoleResponse"]] = Field(None, description="User roles")
    gmt_created: Optional[str] = Field(None, description="Create time")
    gmt_modified: Optional[str] = Field(None, description="Update time")

    model_config = ConfigDict(title=f"UserResponse for {SERVE_APP_NAME_HUMP}")

    def to_dict(self, **kwargs) -> Dict[str, Any]:
        """Convert to dict"""
        return model_to_dict(self, **kwargs)


# ========================================
# Role Schemas
# ========================================
class RoleRequest(BaseModel):
    """Role request model"""

    id: Optional[int] = Field(None, description="Role ID")
    role_code: str = Field(..., description="Role code", min_length=2, max_length=50)
    role_name: str = Field(..., description="Role name", min_length=2, max_length=100)
    role_desc: Optional[str] = Field(None, description="Role description", max_length=500)
    status: Optional[int] = Field(1, description="Status: 1=Active, 0=Disabled")
    remark: Optional[str] = Field(None, description="Remark", max_length=500)
    menu_ids: Optional[List[int]] = Field(None, description="Menu IDs")
    app_codes: Optional[List[str]] = Field(None, description="Application codes")

    model_config = ConfigDict(title=f"RoleRequest for {SERVE_APP_NAME_HUMP}")

    def to_dict(self, **kwargs) -> Dict[str, Any]:
        """Convert to dict"""
        return model_to_dict(self, **kwargs)


class RoleResponse(BaseModel):
    """Role response model"""

    id: int = Field(..., description="Role ID")
    role_code: str = Field(..., description="Role code")
    role_name: str = Field(..., description="Role name")
    role_desc: Optional[str] = Field(None, description="Role description")
    status: int = Field(..., description="Status: 1=Active, 0=Disabled")
    remark: Optional[str] = Field(None, description="Remark")
    menus: Optional[List["MenuResponse"]] = Field(None, description="Role menus")
    app_codes: Optional[List[str]] = Field(None, description="Application codes")
    gmt_created: Optional[str] = Field(None, description="Create time")
    gmt_modified: Optional[str] = Field(None, description="Update time")

    model_config = ConfigDict(title=f"RoleResponse for {SERVE_APP_NAME_HUMP}")

    def to_dict(self, **kwargs) -> Dict[str, Any]:
        """Convert to dict"""
        return model_to_dict(self, **kwargs)


# ========================================
# Menu Schemas
# ========================================
class MenuRequest(BaseModel):
    """Menu request model"""

    id: Optional[int] = Field(None, description="Menu ID")
    parent_id: int = Field(0, description="Parent menu ID, 0=root")
    menu_code: str = Field(..., description="Menu code", min_length=2, max_length=50)
    menu_name: str = Field(..., description="Menu name", min_length=2, max_length=100)
    menu_name_en: Optional[str] = Field(None, description="Menu name (English)", max_length=100)
    menu_type: int = Field(..., description="Menu type: 1=Directory, 2=Menu, 3=Button")
    route_path: Optional[str] = Field(None, description="Route path", max_length=255)
    component_path: Optional[str] = Field(None, description="Component path", max_length=255)
    icon: Optional[str] = Field(None, description="Icon", max_length=100)
    sort_order: int = Field(0, description="Sort order")
    permission_code: Optional[str] = Field(None, description="Permission code", max_length=100)
    status: Optional[int] = Field(1, description="Status: 1=Active, 0=Disabled")
    is_visible: Optional[int] = Field(1, description="Visible: 1=Yes, 0=No")
    remark: Optional[str] = Field(None, description="Remark", max_length=500)

    model_config = ConfigDict(title=f"MenuRequest for {SERVE_APP_NAME_HUMP}")

    def to_dict(self, **kwargs) -> Dict[str, Any]:
        """Convert to dict"""
        return model_to_dict(self, **kwargs)


class MenuResponse(BaseModel):
    """Menu response model"""

    id: int = Field(..., description="Menu ID")
    parent_id: int = Field(..., description="Parent menu ID")
    menu_code: str = Field(..., description="Menu code")
    menu_name: str = Field(..., description="Menu name")
    menu_name_en: Optional[str] = Field(None, description="Menu name (English)")
    menu_type: int = Field(..., description="Menu type: 1=Directory, 2=Menu, 3=Button")
    route_path: Optional[str] = Field(None, description="Route path")
    component_path: Optional[str] = Field(None, description="Component path")
    icon: Optional[str] = Field(None, description="Icon")
    sort_order: int = Field(..., description="Sort order")
    permission_code: Optional[str] = Field(None, description="Permission code")
    status: int = Field(..., description="Status: 1=Active, 0=Disabled")
    is_visible: int = Field(..., description="Visible: 1=Yes, 0=No")
    remark: Optional[str] = Field(None, description="Remark")
    children: Optional[List["MenuResponse"]] = Field(None, description="Children menus")
    gmt_created: Optional[str] = Field(None, description="Create time")
    gmt_modified: Optional[str] = Field(None, description="Update time")

    model_config = ConfigDict(title=f"MenuResponse for {SERVE_APP_NAME_HUMP}")

    def to_dict(self, **kwargs) -> Dict[str, Any]:
        """Convert to dict"""
        return model_to_dict(self, **kwargs)


class MenuTreeResponse(BaseModel):
    """Menu tree response model"""

    menus: List[MenuResponse] = Field(..., description="Menu tree")

    model_config = ConfigDict(title=f"MenuTreeResponse for {SERVE_APP_NAME_HUMP}")


# ========================================
# Auth Schemas
# ========================================
class LoginRequest(BaseModel):
    """Login request model"""

    username: str = Field(..., description="Username", min_length=3)
    password: str = Field(..., description="Password", min_length=6)

    model_config = ConfigDict(title=f"LoginRequest for {SERVE_APP_NAME_HUMP}")

    def to_dict(self, **kwargs) -> Dict[str, Any]:
        """Convert to dict"""
        return model_to_dict(self, **kwargs)


class TokenResponse(BaseModel):
    """Token response model"""

    access_token: str = Field(..., description="Access token")
    token_type: str = Field("Bearer", description="Token type")
    expires_in: int = Field(..., description="Expiration time (seconds)")

    model_config = ConfigDict(title=f"TokenResponse for {SERVE_APP_NAME_HUMP}")


class LoginResponse(BaseModel):
    """Login response model"""

    user: UserResponse = Field(..., description="User information")
    token: TokenResponse = Field(..., description="Token information")
    menus: List[MenuResponse] = Field(..., description="User menus")
    permissions: List[str] = Field(..., description="User permissions")

    model_config = ConfigDict(title=f"LoginResponse for {SERVE_APP_NAME_HUMP}")

    def to_dict(self, **kwargs) -> Dict[str, Any]:
        """Convert to dict"""
        return model_to_dict(self, **kwargs)


# ========================================
# Other Schemas
# ========================================
class ServerResponse(UserResponse):
    """Server response model (for compatibility)"""

    pass


class ServeRequest(UserRequest):
    """Serve request model (for compatibility)"""

    pass
